﻿#region File and License Information
/*
<File>
	<License>
		Copyright © 2009 - 2017, Daniel Vaughan. All rights reserved.
		This file is part of Calcium (http://calciumsdk.net), 
		which is released under the MIT License.
		See file /Documentation/License.txt for details.
	</License>
	<CreationDate>2009-04-11 20:01:19Z</CreationDate>
</File>
*/
#endregion

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Outcoder.Gui;
using Outcoder.Services.DialogService;

namespace Outcoder.Services.Implementation
{
	/// <summary>
	/// WPF implementation of the <see cref="IDialogService"/>.
	/// </summary>
	public class DialogService : DialogServiceBase
	{
		public async override Task<DialogResult> ShowDialogAsync(
								object content, string caption,
								DialogButton dialogButton, 
								DialogImage dialogImage = DialogImage.None,
								DialogImportance importanceThreshold = DialogImportance.High,
								object details = null,
								DialogController dialogController = null)
		{
			/* If the importance threshold has been specified 
			 * and it's less than the minimum level required (the filter level) 
			 * then we don't show the message. */
			if (importanceThreshold < MinumumImportance)
			{
				return DialogResult.OK;
			}

			Window mainWindow = GetMainWindow();
			Dispatcher dispatcher = mainWindow != null ? mainWindow.Dispatcher : Dispatcher.CurrentDispatcher;

			string bodyString = content != null ? content.ToString() : string.Empty;

			if (dispatcher == null || dispatcher.CheckAccess())
			{
				MessageBoxResult messageBoxResult;

				try
				{
					Interlocked.Increment(ref openDialogCount);

					if (mainWindow != null)
					{
						/* We are on the UI thread, and hence no need to invoke the call.*/
						messageBoxResult = MessageBox.Show(mainWindow, bodyString, caption ?? string.Empty, 
							dialogButton.TranslateToMessageBoxButton(), 
							dialogImage.TranslateToMessageBoxButton());
					}
					else
					{
						messageBoxResult = MessageBox.Show(bodyString, caption ?? string.Empty,
							dialogButton.TranslateToMessageBoxButton(),
							dialogImage.TranslateToMessageBoxButton());
					}
				}
				finally
				{
					Interlocked.Decrement(ref openDialogCount);
				}
				
				return messageBoxResult.TranslateToMessageBoxResult();
			}

			DialogResult result = DialogResult.OK; /* Satisfy compiler with default value. */
			dispatcher.Invoke((ThreadStart)delegate
			{
				MessageBoxResult messageBoxResult;

				try
				{
					Interlocked.Increment(ref openDialogCount);

					if (mainWindow != null)
					{
						/* We are on the UI thread, and hence no need to invoke the call.*/
						messageBoxResult = MessageBox.Show(mainWindow, bodyString, caption,
							dialogButton.TranslateToMessageBoxButton(),
							dialogImage.TranslateToMessageBoxButton());
					}
					else
					{
						messageBoxResult = MessageBox.Show(bodyString, caption,
							dialogButton.TranslateToMessageBoxButton(),
							dialogImage.TranslateToMessageBoxButton());
					}
				}
				finally
				{
					Interlocked.Decrement(ref openDialogCount);
				}

				result = messageBoxResult.TranslateToMessageBoxResult();
			});

			return result;
		}

		public async override Task<int?> ShowDialogAsync(
									object question, 
									IEnumerable<object> buttons,
									string caption = null,
									int defaultAcceptButtonIndex = -1,
									object expandableDetails = null,
									DialogController dialogController = null)
		{
			throw new NotImplementedException();
		}

//		public override Task<DialogResult> ShowDialogAsync(
//			object content, string caption, DialogButton dialogButton,
//			DialogImage dialogImage = DialogImage.None, DialogImportance importanceThreshold = DialogImportance.High,
//			object details = null)
//		{
//			throw new NotImplementedException();
//		}

		public async override Task<QuestionResponse<TResponse>> AskQuestionAsync<TResponse>(IQuestion<TResponse> question)
		{
			throw new NotImplementedException();
		}

		//public override Task<TextResponse> AskQuestionWithTextResponse(TextResponseQuestion textResponseQuestion)
		//{
		//	throw new NotImplementedException();
		//}

		static Window GetMainWindow()
		{
			IMainWindow window;
			if (Dependency.TryResolve<IMainWindow>(out window))
			{
				Window result = window as Window;
				if (result != null)
				{
					return result;
				}
			}
			if (Application.Current != null)
			{
				return Application.Current.MainWindow;
			}
			return null;
		}
	}
}
